package xgenerator.dao.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import xgenerator.converter.PropertyTypeConverter;
import xgenerator.converter.DataTypeConverter;
import xgenerator.jdbc.JdbcContext;
import xgenerator.model.FieldMetadata;
import xgenerator.util.NotationUtils;

public class MetadataDaoDb2Impl extends MetadataDaoJdbcAdapter {

	private DataTypeConverter dataTypeConverter;
	private PropertyTypeConverter propertyTypeConverter;

	/**
	 * <p>
	 * Title：获取所有表
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param dataSourceName
	 * @return
	 * @see xgenerator.dao.impl.MetadataDaoJdbcAdapter#getTables(java.lang.String)
	 */
	public Vector<String> getTables(String dataSourceName) {
		Vector<String> tableList = new Vector<String>();
		
		JdbcContext jdbcContext = JdbcContext.getJdbcContext(dataSourceName);
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			conn = jdbcContext.currentConnection();
			stmt = conn.createStatement();
			String sql = "SELECT T.TABLE_NAME FROM USER_TABLES T";
			rs = stmt.executeQuery(sql);
			
			while(rs.next()) {
				tableList.add(rs.getString("TABLE_NAME"));
			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		} finally {
			JdbcContext.close(stmt, rs);
		}
		
		return tableList;
	}

	/**
	 * <p>
	 * Title：获取表注释
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param dataSourceName
	 * @param tableName
	 * @return
	 * @see xgenerator.dao.impl.MetadataDaoJdbcAdapter#getTableComments(java.lang.String, java.lang.String)
	 */
	public String getTableComments(String dataSourceName, String tableName) {
		String tableComments = "";
		
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			conn = JdbcContext.getJdbcContext(dataSourceName).currentConnection();
			stmt = conn.createStatement();
			String sql = "SELECT T.COMMENTS FROM USER_TAB_COMMENTS T WHERE T.TABLE_NAME='" + tableName + "'";
			rs = stmt.executeQuery(sql);
			
			if(rs.next()) {
				tableComments = rs.getString("COMMENTS");
			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		} finally {
			JdbcContext.close(stmt, rs);
		}
		
		return tableComments;
	}
	
	/**
	 * <p>
	 * Title：获取所有列
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param dataSourceName
	 * @param tableName
	 * @return
	 * @see xgenerator.dao.impl.MetadataDaoJdbcAdapter#getTableColumns(java.lang.String, java.lang.String)
	 */
	public Vector<String> getTableColumns(String dataSourceName, String tableName) {
		Vector<String> tableList = new Vector<String>();
		
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			conn = JdbcContext.getJdbcContext(dataSourceName).currentConnection();
			stmt = conn.createStatement();
			String sql = "SELECT T.COLUMN_NAME FROM USER_TAB_COLUMNS T WHERE T.TABLE_NAME='" + tableName + "'";
			rs = stmt.executeQuery(sql);
			
			while(rs.next()) {
				tableList.add(rs.getString("COLUMN_NAME"));
			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		} finally {
			JdbcContext.close(stmt, rs);
		}
		
		return tableList;
	}
	
	/**
	 * <p>
	 * Title：获取列元数据
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param dataSourceName
	 * @param tableName
	 * @return
	 * @see xgenerator.dao.impl.MetadataDaoJdbcAdapter#getTableColumnMetadata(java.lang.String, java.lang.String)
	 */
	public List<FieldMetadata> getTableColumnMetadata(String dataSourceName, String tableName) {
		List<FieldMetadata> tableList = new ArrayList<FieldMetadata>();
		
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			conn = JdbcContext.getJdbcContext(dataSourceName).currentConnection();
			stmt = conn.createStatement();
			String sql = "SELECT T.COLUMN_ID, T.COLUMN_NAME, S.COMMENTS, T.DATA_TYPE, DATA_LENGTH, T.DATA_PRECISION, T.DATA_SCALE, T.NULLABLE, T.DEFAULT_LENGTH, T.DATA_DEFAULT, T.CHAR_LENGTH FROM USER_COL_COMMENTS S, USER_TAB_COLUMNS T WHERE S.COLUMN_NAME=T.COLUMN_NAME AND T.TABLE_NAME='" + tableName + "' ORDER BY T.COLUMN_ID";
			rs = stmt.executeQuery(sql);
			
			FieldMetadata oneFieldMetadata = null;
			while(rs.next()) {
				oneFieldMetadata = new FieldMetadata();
				
				oneFieldMetadata.setColumnName(rs.getString("COLUMN_NAME"));
				oneFieldMetadata.setComments(rs.getString("COMMENTS"));
				oneFieldMetadata.setDisplayName(rs.getString("COMMENTS"));
				String dataType = rs.getString("DATA_TYPE");
				int dataLength = rs.getInt("DATA_LENGTH");
				int dataPrecision = rs.getInt("DATA_PRECISION");
				int dataScale = rs.getInt("DATA_SCALE");
				String sqlType = dataTypeConverter.convert(dataType, dataLength, dataPrecision, dataScale);
				oneFieldMetadata.setSqlDataType(sqlType);
				oneFieldMetadata.setDataLength(dataLength);
				oneFieldMetadata.setDataPrecision(dataPrecision);
				oneFieldMetadata.setDataScale(dataScale);
				String nullableFlag = rs.getString("NULLABLE");
				if("Y".equals(nullableFlag)) {
					oneFieldMetadata.setNullable(true);
				} else {
					oneFieldMetadata.setNullable(false);
				}
				oneFieldMetadata.setDefaultLength(rs.getInt("DEFAULT_LENGTH"));
				oneFieldMetadata.setDataDefault(rs.getString("DATA_DEFAULT"));
				oneFieldMetadata.setCharLength(rs.getInt("CHAR_LENGTH"));
				
				oneFieldMetadata.setPropertyName(NotationUtils.lowerCamelCase(rs.getString("COLUMN_NAME")));
				String propertyType = propertyTypeConverter.convert(sqlType);
				oneFieldMetadata.setPropertyType(propertyType);
				oneFieldMetadata.setKeyField(false); // 是否为键
				oneFieldMetadata.setConstraintType(""); // 键类型
				
				tableList.add(oneFieldMetadata);
			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		} finally {
			JdbcContext.close(stmt, rs);
		}
		
		return tableList;
	}
	
	/**
	 * <p>
	 * Title：策略模式，设置属性类型转换策略
	 * </p>
	 * @param propertyTypeConverter
	 * @see xgenerator.dao.MetadataDao#setPropertyTypeConverter(xgenerator.converter.PropertyTypeConverter)
	 */
	public void setPropertyTypeConverter(PropertyTypeConverter propertyTypeConverter) {
		this.propertyTypeConverter = propertyTypeConverter;
	}

	/**
	 * @return the propertyTypeConverter
	 */
	public PropertyTypeConverter getPropertyTypeConverter() {
		return this.propertyTypeConverter;
	}
	
}
